home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 6867 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  4.8 KB

  1. Path: qualcomm.com!usenet
  2. From: nabbasi@qualcomm.com (Nasser Abbasi)
  3. Newsgroups: comp.programming.threads,comp.lang.c++,comp.unix.osf.osf1,comp.unix.programmer,comp.object
  4. Subject: Re: Looking for best design for using pthreads in C++ objects
  5. Date: 20 Feb 1996 08:00:51 GMT
  6. Organization: QUalcomm Inc.
  7. Message-ID: <4gbv3j$g08@qualcomm.com>
  8. References: <3128ff8b.666031216@news.clark.net>
  9. Reply-To: x!news.be.innet.net!INbe.net!usenet
  10. NNTP-Posting-Host: annex-p15.qualcomm.com
  11. X-Newsreader: WinVN 0.90.4
  12.  
  13. In article <3128ff8b.666031216@news.clark.net>, anderson@clark.net (Thom Anderson) says:
  14. >
  15. >I am starting to port a design that was meant to be implemented in Ada to a
  16. >C++/UNIX platform.  I don't want to get involved in any language religion here,
  17. >but it will be much harder to handle tasking with C++.  My best alternative
  18. >(maybe only - since I must be POSIX compliant) is to use pthreads.
  19. >
  20. >I have used pthreads from C before but not from C++.  I have a couple of ideas
  21. >in mind but neither is elegant.  Does anyone have any experience with
  22. >C++/Pthreads and no of some good design solutions, tips, or ideas???
  23. >
  24.  
  25. I have implemented a C++ Base Thread class that allows threads cross 
  26. communications using message queues. 
  27.  
  28. The idea is that you have a base thread class, with public interface
  29. access functions to create a thread (can be implemented using Pthread
  30. or whatever thread package you have), and to READ/WRITE from thread
  31. Input and Output Queues. You also need to have a pure virtual 
  32. function that is the address of thread function code itself which the
  33. derived classes have to provide. This way each specialized class can use
  34. different thread functions. 
  35.  
  36. Now, assume you have created 2 threads objects, A and B. A uses function
  37. A_foo() as the thread function, and B say uses B_foo() as the B thread
  38. function.
  39.  
  40. For A to send a message to B, A will invoke a public access function in B
  41. that will deposit a message inside a private Queue in B and will then wake
  42. up B (B thread id is saved in private part of B class object )and return. 
  43.  
  44. Each thread can once in a while can check its input Queue to see if it has 
  45. messages to process. If no message, it will sleep until awakened (or 
  46. sleep for certain period, then tries again etc...).
  47.  
  48. If you want to implement a driver type of thread, (passive thread) you can
  49. also have the thread object contain an output Queue (in addition to 
  50. Input Queue), and the thread will deposit processed messages (work 
  51. completed) in its output Queue and will then wake any waiting thread on
  52. its output Queue (the readers). (in first-in-first_out fashion).
  53.  
  54. Each reader will invoke a READ access public function in the thread class,
  55. where this READ access function will access the thread private output
  56. Queue and if there is data, it will remove it, and return, else it will
  57. sleep (block) on the Queue (saves its thread_id in waiters Queue) so
  58. that when the driver thread has data to send out, it will put it in its
  59. output Queue, check the waiters/readers queue, wake up the first in 
  60. line using the reader thread_id). Offcourse you do not have to have
  61. the read block if there is no data. you can have a time_out value, or
  62. other combination.
  63.  
  64. I do not know Pthreads much, so I do not know if you also need some 
  65. kind of signal number to use in addition to the thread_id to wake up
  66. a thread (You need to look at the Pthread Wake thread API), but if you
  67. do, that is easy to also pass along with the thread_id to allow the 
  68. other thread to wake your thread. (i.e. each Input and Output Queue 
  69. for each thread  will have a signal number associated with it).
  70.  
  71. All in All, you need to spend good time designing the thread class,
  72. and hide all the threads-cross communications in the private part of
  73. the class. Using Queues to accomplish the message exchanging is the 
  74. most natural way.
  75.  
  76. One thing to worry about is how much time a caller thread will spend
  77. in the access function of the other thread object. While executing 
  78. the access function inside one thread object the client thread is 
  79. executing in its own  context ,which might have higher priority that
  80. the called thread object, and so things like blocking inside the 
  81. access function need to be thought out well to make sure that is 
  82. what you want to do. (to prevent among other things possible dead-lock).
  83.  
  84. It is really not that hard, I have implemented the complete class in about
  85. 1-2 week, it is 3 layers in class hierarchy, and it is about 500-600 
  86. lines of code (and this was the first time I looked at this problem
  87. of using C++ classes and threads.
  88.  
  89. offcourse you need to have access to thread-safe Queue classes.
  90.  
  91. If you on the other hand decide to use Ada , you'll have easier time,
  92. since Ada as you know already solves many of these problems for you, 
  93. by providing tasks and protected objects, the Requeue facility, Rendezvous,
  94. Asynchronous transfer of control, and many other features for
  95. task-to-task interactions.
  96.  
  97. Nasser
  98.